package com.zengdada.authority.utils.mapper;

import org.apache.commons.lang3.StringUtils;

import javax.persistence.Column;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.zengdada.authority.utils.CommonUtils.humpToLine;

/**
 * @author 12614
 * @contact 1261438511@qq.com
 * @date 2018/11/4 16:39
 * @description 通用排序
 */
public class Sort {
    public enum SortWay {
        /**
         * 正序
         */
        ASC,
        /**
         * 倒序
         */
        DESC
    }

    private String field;
    private String order = "";
    private static Pattern humpPattern = Pattern.compile("[A-Z]");
    private static Pattern sqlCheck = Pattern.compile("[A-Za-z0-9\\_]+$");

    public Sort() {
    }

    public Sort(String field, String order) {
        this.field = field;
        this.order = order;
    }

    public Sort(String field) {
        this.field = field;
    }

    public Sort(String field, SortWay order) {
        this.field = field;
        if (order != null) {
            this.order = order.name();
        }
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        if (!sqlCheck.matcher(field).matches()) {
            throw new RuntimeException(String.format("错误的排序字段‘%s’", field));
        }
        this.field = field;
    }

    public void setFieldNotValidate(String field) {
        setFieldValidate(field, false);
    }

    public void setFieldValidate(String field, Boolean validate) {
        if (validate && !sqlCheck.matcher(field).matches()) {
            throw new RuntimeException(String.format("错误的排序字段‘%s’", field));
        }
        this.field = field;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        if ("".equals(order)) {
            this.order = order;
        }
        SortWay sortWay;
        try {
            sortWay = SortWay.valueOf(order.toUpperCase());
            this.order = sortWay.name();
        } catch (IllegalArgumentException e) {
            this.order = "";
        }
    }

    public void setOrderE(SortWay order) {
        if (order != null) {
            this.order = order.name();
        }
    }


    /**
     * 获取排序语句 并 将驼峰命名转换为数据库命名
     *
     * @return
     */

    public String getOrderDetailed() {
        return isNotNull() ? humpToLine(field) + " " + order : null;
    }

    /**
     * 获取排序语句 控制命名转换
     *
     * @param ishump 是否将驼峰命名转换为数据库命名
     * @return
     */
    public String getOrderDetailed(boolean ishump) {
        return isNotNull() ? (ishump ? humpToLine(field) : field) + " " + order : null;
    }

    /**
     * 获取排序语句 并 将驼峰命名转换为数据库命名 判断实体类中是否有该字段
     *
     * @return
     */
    public String getOrderDetailed(Class<?> actualClass) {
        if (!isNotNull()) {
            return null;
        }
        Field[] fields = actualClass.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Column.class)) {
                Column annotation = field.getAnnotation(Column.class);
                String name = annotation.name();
                if (StringUtils.isNoneBlank(name) && name.toUpperCase().equals(humpToLine(this.field).toUpperCase())) {
                    return humpToLine(this.field) + " " + this.order;
                }
            }
        }
        throw new RuntimeException(String.format("‘%s’无效的排序字段", this.field));
    }

    /**
     * 获取排序语句 控制命名转换 判断实体类中是否有该字段
     *
     * @param ishump 是否将驼峰命名转换为数据库命名
     * @return
     */
    public String getOrderDetailed(boolean ishump, Class<? extends Type> actualClass) {
        if (!isNotNull()) {
            return null;
        }
        Field[] fields = actualClass.getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Column.class)) {
                Column annotation = field.getAnnotation(Column.class);
                String name = annotation.name();
                if (StringUtils.isNoneBlank(name) && (name.toUpperCase().equals(humpToLine(ishump ? humpToLine(this.field) : this.field).toUpperCase()))) {
                    return (ishump ? humpToLine(this.field) : this.field) + " " + this.order;
                }
            }
        }
        throw new RuntimeException(String.format("‘%s’无效的排序字段", this.field));
    }

    /**
     * 是否不为空
     *
     * @return true 不为空 false 空
     */
    public boolean isNotNull() {
        return field != null && !"".equals(field) && null != order;
    }


//    public static String humpToLine(String str) {
//        if (str.contains("_") || Pattern.compile("[a-z0-9]*").matcher(str).matches() || Pattern.compile("[A-Z0-9]*").matcher(str).matches())
//            return str.toUpperCase();
//        Matcher matcher = humpPattern.matcher(str);
//        StringBuffer sb = new StringBuffer();
//        while (matcher.find())
//            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
//        matcher.appendTail(sb);
//        return sb.toString().toUpperCase();
//    }
}
